﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
using System.Diagnostics;
using System.Windows.Threading;
using System.Collections.ObjectModel;
using System.Windows.Controls;
using System.Windows;

namespace PatientInformationExtract.MainInterface.Models
{
    public class RetrieveFileModel
    {
        private ObservableCollection<ICheckableItem> _treeRoot;

        private List<string> _patientList;
        public List<string> PatientList { get { return this._patientList; } }
        private List<string> _folderPathes;
        public List<string> FolderPathes { get { return this._folderPathes; } }

        public ObservableCollection<PatientListTreeItem> _patientListView;
        public ObservableCollection<PatientListTreeItem> PatientListView { get { return this._patientListView; } }

        public enum RetrieveFileOption
        {
            AddAllRepeatedPatient,
            AddRepeatedPatientAfterQuestion,
            AddNoRepeatedPatient,
        }

        public RetrieveFileModel(ObservableCollection<ICheckableItem> treeRoot)
        {
            this._treeRoot = treeRoot;
            this._patientList = new List<string>();
            this._patientListView = new ObservableCollection<PatientListTreeItem>();
        }

        public void RetrieveCheckedPatientList()
        {
            this._patientList = new List<string>();
            foreach (ICheckableItem item in this._treeRoot)
            {
                if (item.IsChecked != false)
                {
                    if (item.IItems != null)
                    {
                        GetPatientFolderPath(item, ref this._patientList);
                    }
                }
            }
        }

        public void RetrieveCheckedItemTags()
        {
            this._folderPathes = new List<string>();
            foreach (ICheckableItem item in this._treeRoot)
            {
                if (item.IsChecked != false)
                {
                    if (item.IItems != null)
                    {
                        GetFolderPath(item, ref this._folderPathes);
                    }
                }
            }
        }

        public void PatientListAfterProcess(RetrieveFileOption option)
        {
            if (this._patientList.Count != 0)
            {
                Regex regexPatientID = new Regex(@"^(\w+)_\d+");
                Regex regexVisitID = new Regex(@"\d+_(\d*)$");
                Dictionary<string, PatientListTreeItem> patientIDs = new Dictionary<string, PatientListTreeItem>();
                foreach (string str in this._patientList.ToArray())
                {
                    DirectoryInfo di = new DirectoryInfo(str);
                    string patientID = regexPatientID.Match(di.Name).Groups[1].ToString();
                    string visitID = regexVisitID.Match(di.Name).Groups[1].ToString();
                    if (patientID != "" && visitID != "")
                    {
                        if (patientIDs.ContainsKey(patientID))
                        {
                            bool isVisitIDRepeat = false;
                            PatientListTreeItem itemPatientID;
                            patientIDs.TryGetValue(patientID, out itemPatientID);
                            foreach (PatientListTreeItem item in itemPatientID.Items)
                            {
                                if (visitID.Equals(item.Header))
                                {
                                    isVisitIDRepeat = true;
                                    break;
                                }
                            }
                            if (!isVisitIDRepeat)
                            {
                                PatientListTreeItem itemVisitID = new PatientListTreeItem();
                                itemVisitID.Header = visitID;
                                itemVisitID.Tag = str;
                                itemPatientID.Items.Add(itemVisitID);
                            }
                            else
                            {
                                switch (option)
                                {
                                    case RetrieveFileOption.AddRepeatedPatientAfterQuestion:
                                        {
                                            if (MessageBox.Show(di.Name + " Patient Folder Already Exists, Do you still want to add it to PatientList?", "Already Exist", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes)
                                            {
                                                PatientListTreeItem itemVisitID = new PatientListTreeItem();
                                                itemVisitID.Header = visitID;
                                                itemVisitID.Tag = str;
                                                itemPatientID.Items.Add(itemVisitID);
                                            }
                                            else
                                            {
                                                this._patientList.Remove(str);
                                            }
                                            break;
                                        }
                                    case RetrieveFileOption.AddNoRepeatedPatient:
                                        {
                                            this._patientList.Remove(str);
                                            break;
                                        }
                                    case RetrieveFileOption.AddAllRepeatedPatient:
                                        {
                                            PatientListTreeItem itemVisitID = new PatientListTreeItem();
                                            itemVisitID.Header = visitID;
                                            itemVisitID.Tag = str;
                                            itemPatientID.Items.Add(itemVisitID);
                                            break;
                                        }
                                }
                            }
                        }
                        else
                        {
                            PatientListTreeItem itemPatientID = new PatientListTreeItem();
                            itemPatientID.Header = patientID;
                            PatientListTreeItem itemVisitID = new PatientListTreeItem();
                            itemVisitID.Header = visitID;
                            itemVisitID.Tag = str;
                            itemPatientID.Items.Add(itemVisitID);
                            this._patientListView.Add(itemPatientID);
                            patientIDs.Add(patientID, itemPatientID);
                        }
                    }
                    else
                    {
                        PatientListTreeItem item = new PatientListTreeItem();
                        item.Header = str;
                        item.Tag = str;
                        this._patientListView.Insert(0, item);
                    }
                }
                foreach (PatientListTreeItem it in this._patientListView)
                {
                    int count = it.Items.Count;
                    if (count != 0)
                    {
                        it.Header += "(" + count.ToString() + ")";
                    }
                }
            }
        }

        /// <summary>
        /// 递归获取所选文件夹或磁盘下的所有最底层子文件夹
        /// </summary>
        /// <param name="item">目录树变量</param>
        /// <param name="folderPath">存储最底层子文件夹的变量</param>
        /// <returns>返回存储最底层子文件夹的变量</returns>
        private void GetFolderPath(ICheckableItem item, ref List<string> folderPath)
        {
            foreach (ICheckableItem subitem in item.IItems)
            {
                if (subitem.IsChecked != false)
                {
                    if (subitem.IItems != null)
                    {
                        GetFolderPath(subitem, ref folderPath);
                    }
                    else
                    {
                        folderPath.Add(subitem.Tag);
                    }
                }
            }
        }

        /// <summary>
        /// 递归获取所选文件夹或磁盘下的所有病人文件夹
        /// </summary>
        /// <param name="dt">目录树</param>
        /// <param name="patientFolderPath">存储最底层子文件夹</param>
        /// <returns>返回存储最底层子文件夹</returns>
        private void GetPatientFolderPath(ICheckableItem item, ref List<string> patientFolderPath)
        {
            if (item is DirectoryTree)
            {
                DirectoryTree dt = item as DirectoryTree;

                foreach (DirectoryTree dirs in dt.Directories)
                {
                    if (dirs.IsChecked != false)
                    {
                        if (dirs.Directories != null)
                        {
                            GetPatientFolderPath(dirs, ref patientFolderPath);
                        }
                        else
                        {
                            try
                            {
                                foreach (FileInfo f in dirs.Info.GetFiles())
                                {
                                    if (f.Extension == ".XLS")
                                    {
                                        if (f.Name.Equals("d_lab.XLS") || f.Name == "d_vital_sign.XLS" || f.Name == "d_exam.XLS" || f.Name == "d_orders.XLS")
                                        {
                                            patientFolderPath.Add(dirs.Info.FullName);
                                            break;
                                        }
                                    }
                                    if (Regex.IsMatch(f.Name, @"00\d.htm$", RegexOptions.IgnoreCase))
                                    {
                                        HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
                                        try
                                        {
                                            doc.Load(f.FullName);
                                            if (doc.DocumentNode.SelectSingleNode(@"/html[1]/body[1]/table[1]/tr[1]/td[1]/table[1]/tr[1]/td[1]/p[1]").InnerText.Replace(@"&nbsp;", "").Equals("中国人民解放军总医院"))
                                            {
                                                patientFolderPath.Add(dirs.Info.FullName);
                                                break;
                                            }
                                        }
                                        catch
                                        {
                                            doc = null;
                                        }
                                    }

                                }
                            }
                            catch { }

                        }
                    }
                }
            }
        }

        /// <summary>
        /// 获取文件夹下经过筛选的文件路径
        /// </summary>
        /// <param name="folderPath">文件夹路径</param>
        /// <param name="suffix">后缀</param>
        /// <param name="keyWord">关键词</param>
        /// <returns>返回文件路径列表</returns>
        private List<string> GetFilePath(string folderPath, string suffix, string keyWord)
        {
            List<string> filePath = new List<string>();
            try
            {
                DirectoryInfo dires = new DirectoryInfo(folderPath);
                FileInfo[] files = dires.GetFiles();
                foreach (FileInfo f in files)
                {
                    if (suffix.Length != 0)
                    {
                        if (Regex.IsMatch(f.Name, suffix, RegexOptions.IgnoreCase))
                        {
                            if (keyWord.Length != 0)
                            {
                                if (Regex.IsMatch(f.Name, keyWord, RegexOptions.IgnoreCase))
                                {
                                    filePath.Add(f.FullName);
                                }
                            }
                            else
                                filePath.Add(f.FullName);
                        }
                    }
                    else
                        filePath.Add(f.FullName);
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.StackTrace);
            }
            return filePath;
        }
    }
}
